import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.Resource;
import com.sun.org.apache.xalan.internal.xsltc.dom.MultiValuedNodeHeapIterator;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.AbstractContextLoaderInitializer;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.*;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.*;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.mvc.*;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import org.springframework.web.servlet.mvc.support.ControllerBeanNameHandlerMapping;
import org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
import org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.AbstractUrlBasedView;
import org.springframework.web.util.IntrospectorCleanupListener;
import org.springframework.web.util.Log4jConfigListener;
import org.yangspring.samples.mvc.simple2.ControllerClassNameController;

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Proxy;
import java.util.Deque;
import java.util.PriorityQueue;

/**
 * Created by whyang on 2017/06/09.
 */

public class SvrStarter {

    public static void main(String[] args){

        /*System.out.println("SvrStart running 8090");
        Server svr = new Server(8090);

        WebAppContext webapp = new WebAppContext();
        webapp.setResourceBase("webapp");
        webapp.setDescriptor("webapp/WEB-INF/web.xml");
        webapp.setContextPath("/");
        webapp.setClassLoader(Thread.currentThread().getContextClassLoader());

        svr.setHandler(webapp);
        try {
            svr.start();
            svr.join();
        } catch (InterruptedException ie ){
        } catch (Exception e) {
        }*/



        sfwefwef();


    }


    /*public void startJettySvr(){
        Server server = new Server(8080);
        ContextHandler context = new ContextHandler();
        context.setContextPath("/");
        context.setResourceBase(".");
        context.setClassLoader(Thread.currentThread().getContextClassLoader());
        server.setHandler(context);
        context.setHandler(new HelloHandler());
        try {
            server.start();
            server.join();
        } catch (Exception e) {
        }
    }*/

    /*public void startJettySvr2(){
        Server server = new Server();
        Connector connector = new SelectChannelConnector();
        connector.setPort(8080);
        server.setConnectors(new Connector[]{ connector });
        ServletContextHandler root = new
                ServletContextHandler(null,"/",ServletContextHandler.SESSIONS);
        server.setHandler(root);
        root.addServlet(new ServletHolder(new HelloServlet("Hello")),"/");
        try{
            server.start();
            server.join();
        } catch (Exception e){
        }
    }*/


    public void ssvsdvsd (){

        /*@javax.servlet.annotation.WebListener
        class WebListener  {

        }*/

        ServletContainerInitializer svltCntnrInitor;

        HttpServlet httpSvlt;
        DispatcherServlet dispatcherServlet;
        ServletContainerInitializer svltCntnrInitor2;
        ServletContextListener svltCntxLsnr;
        WebApplicationInitializer webACInitor;
        ParameterizableViewController paramViewCtrl;

        Controller ctrl;
        WebMvcConfigurer webMvcConfigurer;
        ServletContextListener svltCntxLsnr2;
        WebApplicationInitializer webApplicationInitializer;
        ContextLoaderListener contextLoaderListener;

        WebApplicationContext wac;
        FrameworkServlet frameworkServlet;

        //  start
        HttpServletRequest wewefwef;
        HttpServletResponse fwefweoifpwoefp;
        //  end

        ContextLoader cntxldr;
        ContextLoaderListener cll;

        ServletConfig svltcfg;
        Servlet svlt;
        ServletContext sc;
        ServletContextListener svltCntxLsnr4;
        HttpServlet httpsvlt;

        AbstractAnnotationConfigDispatcherServletInitializer wefwef134030g92j30g9;

        HttpMessageConverter httpMsgCvtr;
        RequestResponseBodyMethodProcessor reqRespBdMtdPrcs;

        //  start
        HandlerMethod mhhhe;
        RequestMappingInfo weognweoigwe;

        HandlerAdapter hndlAdpt;
        AbstractHandlerMethodMapping fwefwef;

        HandlerExecutionChain fwefwe2323f;
        //  end


        //  start
        //  mapping 映射器
        HandlerMapping hndlMapp;
        ExceptionHandlerExceptionResolver excpHndlExcpRslv;

        HandlerMethodArgumentResolverComposite cdc;

        Controller ctrl2;

        ModelAndView mv3;
        View v333;
        ViewResolver vrsv;
        AbstractUrlBasedView fsfsdf;

        LocaleResolver lclRslvr;
        InternalResourceViewResolver irvsvlr;

        HandlerExceptionResolver hndlExcpRsvl;

        SimpleMappingExceptionResolver xdvsdv;

        ModelAndView mav;

        MultiActionController mactrl;

        DefaultRequestToViewNameTranslator defReq2ViewTrslt;
        RequestToViewNameTranslator ewfwefwef;


        WebMvcConfigurerAdapter ewe;

//        org.springframework.web.servlet.config.annotation.*;


        ContextLoader wefwef;
        Controller fwevwve232;
        Servlet o3rbi3490g93409;
        HttpRequestHandler g3049jg034g0934;
        ServletContextListener wfwefwef;

        HandlerMethod g3g34g;

        AsyncHandlerInterceptor gj304gj3049g;
            HandlerInterceptorAdapter g34g34g34g;
            WebRequestHandlerInterceptorAdapter fh2039f02930j;
        WebContentInterceptor fh2309g2j039gj0;


        /**
         *
         * （印象中，之前在 code 里记录过 类似的笔记，找不到在那个 proj 里面了，这里再记录一次）
         *
         * SpringMVC 框架有很多组件，其中涉及 Handler 的 Mapping 和 Execute 的组件有 3 个；
         * 当然，Handler 未必 会被认为 是一个 组件。但是要理解 Handler 的处理逻辑，必须 把 Handler 当作一个组件。
         *
         * 通过 HandlerMapping 可以找到 某个 handler；而 Handler 可以有多种形态，比如 一个 Controller，一个 Servlet，etc。
         * 不同的 handler 要 execute，肯定需要不同的套路；
         * 比如 Controller 的成员方法是 handleRequest，而 Servlet 的 成员方法 是 init-service-destroy。
         * 所以，不同类型的 Handler 由对应的 HandlerAdapter 来完成 execute。
         *
         *
         * 下面是 SpringMVC 框架中 涉及的 HandlerAdapter 和 对应的 Handler（Handler 是个概念，并非具体的组件）
         *
         *      HandlerAdaper                                           ：      Handler
         * HttpRequestHandlerAdapter                                    ：   HttpRequestHandler
         * SimpleControllerHandlerAdapter                               ：   Controller
         * AnnotationMethodHandlerAdapter/RequestMappingHandlerAdapter  ：   HanderMethod/@HandlerMapping
         * SimpleServletHandlerAdapter                                  ：   Servlet
         *
         *
         * HandlerMapping 的 4 种实现（与上面的 HandlerAdapter 没有对应关系）：
         *      BeanNameUrlHandlerMapping
         *      ControllerClassNameHandlerMapping(???)
         *      SimpleUrlHandlerMapping
         *      DefaultAnnotationHandlerMapping(Deprecated)
         *      RequestMappingHandlerMapping(@Controller + @RequestMapping)
         *      
         * */
        
    }


    public static void sfwefwef(){

        System.out.println(String.format("\n\n\t:\t%s\n\n", WebApplicationContext.class.getName()));

//        ServletContext sc = null;
//        WebApplicationContext wac = WebApplicationContextUtils.findWebApplicationContext(sc);

//        ServletContext scb = wac.getServletContext();

        System.out.println(String.format("\n\t:%s\t\n", FrameworkServlet.class.getName() + ".CONTEXT."));

        ServletContext sc;

        ServletContextListener gj3gh034jg093j4g;
            IntrospectorCleanupListener frr34g099j304gj09;
            ContextLoaderListener fff3g490j09j3094gj;
            Log4jConfigListener if034j0394jg;


        ModelAttribute f34g0j0394jg09;
        //  这个注解必须与 ControllerAdvice 配合使用吗？如果可以单独使用，其作用范围是什么？


        Reader rdr;
        Writer wtr;
    }

}


class ServletContextTest2 extends HttpServlet {

    public void doGet(HttpServletRequest req, HttpServletResponse res){
        try{
            //中文乱码
            res.setContentType("text/html;charset=gbk");

            PrintWriter pw = res.getWriter();

            //1：得到Servlet Context
            ServletContext sc = this.getServletContext();

            //2: 得到 属性和对应的值

            String info = (String)sc.getAttribute("wuxinliulei");

            pw.println("wuxinliulei = "+info);


        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

    public void doPost(HttpServletRequest req,HttpServletResponse res){
        this.doGet(req,res);
    }

}


class ViewResolverURLBaseViewRsvlIntroduce {

    /*

    org.springframework.web.servlet.view.UrlBasedViewResolver
    public class UrlBasedViewResolver extends AbstractCachingViewResolver implements Ordered
java.lang.Object
    org.springframework.context.support.ApplicationObjectSupport
    org.springframework.web.context.support.WebApplicationObjectSupport
    org.springframework.web.servlet.view.AbstractCachingViewResolver
    org.springframework.web.servlet.view.UrlBasedViewResolver
    将视图直接解析为对应的URL，不需要显示映射定义（若视图名和资源名称一样，就是不需要在spring配置文件中定义）。
    Simple implementation of the ViewResolver interface, allowing for direct resolution of symbolic view names to URLs, without explicit mapping definition. This is useful if your symbolic names match the names of your view resources in a straightforward manner (i.e. the symbolic name is the unique part of the resource's filename), without the need for a dedicated mapping to be defined for each view.
            ViewResolver接口的简单实现，把view名直接解析为url，不需要在上下文中显式定义。当你的view符号名称和它匹配view资源名称一致时，就没有必要为每一个view进行映射了。
            Supports AbstractUrlBasedView subclasses like InternalResourceView, VelocityView and FreeMarkerView. The view class for all views generated by this resolver can be specified via the "viewClass" property.
            它支持AbstractUrlBasedView的子类，如InternalResourceView，VelocityView， FreeMarkerView。可以通过viewClass属性来指定这个视图解析器生成视图的视图类。
                                                                                                                                                                                                                                                                               View names can either be resource URLs themselves, or get augmented by a specified prefix and/or suffix. Exporting an attribute that holds the RequestContext to all views is explicitly supported.
            视图名称可以是URL资源本身，也可以通过指定前缀和后缀。
                                                                                                                                                                                                                                                                               Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" -> "/WEB-INF/jsp/test.jsp"
    例如，若prefix="/WEB-INF/jsp/", suffix=".jsp"，那么视图名"test"就会被转化为 "/WEB-INF/jsp/test.jsp"。
    As a special feature, redirect URLs can be specified via the "redirect:" prefix. E.g.: "redirect:myAction.do" will trigger a redirect to the given URL, rather than resolution as standard view name. This is typically used for redirecting to a controller URL after finishing a form workflow.
    一个特殊功能，可以通过"redirect:"前缀来重定向（redirect） 一个URL，例如，"redirect:myAction.do"将触发一个重定向（redirect）给给定的URL，并不是返回一个标准的视图名字。这通常用于在完成一个表单工作流后重定向一个控制URL。
    Furthermore, forward URLs can be specified via the "forward:" prefix. E.g.: "forward:myAction.do" will trigger a forward to the given URL, rather than resolution as standard view name. This is typically used for controller URLs; it is not supposed to be used for JSP URLs - use logical view names there.
            此外，可以通过" forward:"前缀来转发（forward） 一个URL。例如，"forward:myAction.do"将触发一个转发（forward）给给定的URL，并不是返回一个标准的视图名字。这通常用于控制URL；它不支持使用视图名来映射的JSP路径。
    Note: This class does not support localized resolution, i.e. resolving a symbolic view name to different resources depending on the current locale.
            注意，这个类不支持本地化，就是它不支持根据当前区域作为参数来解析不同的资源的方式。
    Note: When chaining ViewResolvers, a UrlBasedViewResolver will check whether the specified resource actually exists. However, with InternalResourceView, it is not generally possible to determine the existence of the target resource upfront. In such a scenario, a UrlBasedViewResolver will always return View for any given view name; as a consequence, it should be configured as the last ViewResolver in the chain.
            注意，在一组ViewResolver链中，UrlBasedViewResolver不管指定的资源是否存在它都将会检查。然而，在解析InternalResourceView视图时，一般不可能预先知道目标资源是否存在。在这种情况下，UrlBasedViewResolver将始终返回一个视图，因此，它一般定义在视图解析链的最后。
    Set方法
    void  setAttributes(Properties props)
    Set static attributes from a java.util.Properties object, for all views returned by this resolver.
    This is the most convenient way to set static attributes. Note that static attributes can be overridden by dynamic attributes, if a value with the same name is included in the model.
            通过java.util.Properties对象为所有由这个解析器返回的视图设置静态属性。
    注意，这个静态属性可以被动态属性覆盖，若model中有一个相同的属性。
    void  setAttributesMap(Map attributes)
    Set static attributes from a Map, for all views returned by this resolver.
            通过Map对象为所有由这个解析器返回的视图设置静态属性。
    void  setContentType(String contentType)
    Set the content type for all views.
    为所有由这个解析器返回的视图设置content type。
    void  setOrder(int order)
    Set the order in which this ViewResolver is evaluated.
    void  setRedirectContextRelative(boolean redirectContextRelative)
    Set whether to interpret a given redirect URL that starts with a slash ("/") as relative to the current ServletContext, i.e. as relative to the web application root.
            设置是否允许"/"表示根路径。
    void  setRedirectHttp10Compatible(boolean redirectHttp10Compatible)
    Set whether redirects should stay compatible with HTTP 1.0 clients.
            设置是否支持HTTP 1.0的redirect。
    void  setRequestContextAttribute(String requestContextAttribute)
    Set the name of the RequestContext attribute for all views.
    为所有由这个解析器返回的视图设置request context属性。
    void  setPrefix(String prefix)
    Set the prefix that gets prepended to view names when building a URL.
            前缀
    void  setSuffix(String suffix)
    Set the suffix that gets appended to view names when building a URL.
            后缀。
    void  setViewClass(Class viewClass)
    Set the view class that should be used to create views.
    设置这个视图解析器创建视图的类
    void  setViewNames(String[] viewNames)
    Set the view names (or name patterns) that can be handled by this ViewResolver. View names can contain simple wildcards such that 'my*', '*Report' and '*Repo*' will all match the view name 'myReport'.
    设置可以被这个解析器处理的视图名称或视图名称模式。
    UrlBasedViewResolver的应用
            <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"


    */


}
